from flask import g, redirect, url_for, render_template, abort, request, jsonify, current_app

from info import db
from info.modules.user import user_blu
from info.utils.common import user_login_data, file_upload

# 个人中心
from info.utils.constants import USER_COLLECTION_MAX_NEWS, QINIU_DOMIN_PREFIX
from info.utils.models import UserCollection, Category, News
from info.utils.response_code import RET, error_map


# 个人中心首页
@user_blu.route('/user_info')
@user_login_data
def user_info():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆重定向到首页
        return redirect(url_for("home.index"))

    return render_template("news/user.html", user=user.to_dict())


# 基本资料
@user_blu.route('/base_info', methods=['GET', 'POST'])
@user_login_data
def base_info():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)

    # 1GET展示
    if request.method == "GET":
        return render_template("news/user_base_info.html", user=user.to_dict())

    # 2POST提交资料
    # 获取参数
    signature = request.json.get("signature")
    nick_name = request.json.get("nick_name")
    gender = request.json.get("gender")

    # 3/校验参数
    if not all([signature, nick_name, gender]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    if gender not in ["MAN", "WOMAN"]:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    # 4/修改用户数据
    user.nick_name = nick_name
    user.signature = signature
    user.gender = gender

    # 5/*返回json数据
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])  # 与前段定义的规则包文档


# 头像设置
@user_blu.route('/pic_info', methods=['GET', 'POST'])
@user_login_data
def pic_info():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)

    # 1/GET展示
    if request.method == "GET":
        return render_template("news/user_pic_info.html", user=user.to_dict())

    # POST提交数据
    # 2获取文件参数
    avatar_file = request.files.get("avatar")
    try:
        file_bytes = avatar_file.read()
        print(file_bytes)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    # 上传文件到七牛云服务器，一般会将文件单独管理起来，业务服务器&文件服务器
    try:
        file_name = file_upload(file_bytes)
        print(file_name)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
    # 3修改头像链接   #自定义网站图片名称 QINIU_DOMIN_PREFIX已经封装的函数
    user.avatar_url = file_name
    # 4/*返回json数据
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data=user.to_dict())  # 与前段定义的规则包文档


# 密码设置
@user_blu.route('/pass_info', methods=['GET', 'POST'])
@user_login_data
def pass_info():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)

    # 1/GET展示
    if request.method == "GET":
        return render_template("news/user_pass_info.html")

    # 2POST提交参数/获取参数
    old_password = request.json.get("old_password")
    new_password = request.json.get("new_password")

    ##3校验参数
    if not all([new_password, old_password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    # 验证旧密码
    if not user.check_password(old_password):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    # 4修改旧密码
    user.password = new_password

    # 5json返回
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])  # 与前段定义的规则包文档


# 我的收藏页面
@user_blu.route('/collection')
@user_login_data
def collection():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)

    # 1获取参数
    p = request.args.get("p", 1)

    # 2校验参数
    try:
        p = int(p)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)

    # 3查询当前用户的收藏新闻  分页查询
    try:
        pn = user.collection_news.order_by(UserCollection.create_time.desc()).paginate(p, USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
        return abort(500)

    data = {
        "news_list": [news.to_dict() for news in pn.items],
        "total_page": pn.pages,
        "cur_page": pn.page
    }

    # 4数据传入模板渲染
    return render_template("news/user_collection.html", data=data)


# 新闻发布
@user_blu.route('/news_release', methods=['GET', 'POST'])
@user_login_data
def news_release():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)
    # GET展示页面
    if request.method == "GET":
        # 查询分类表的数据
        try:
            categories = Category.query.filter(Category.id != 1).all()
        except BaseException as e:
            # 包装进日记做记录
            current_app.logger.error(e)
            return abort(500)
        # 将数据传入模板
        return render_template("news/user_news_release.html", categories=categories)

    # POST
    # 1获取参数  #需要上传文件用form
    title = request.form.get("title")
    category_id = request.form.get("category_id")
    digest = request.form.get("digest")
    content = request.form.get("content")
    img_file = request.files.get("index_image")

    # 2校验参数
    if not all([title, category_id, digest, content, img_file]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    try:
        category_id = int(category_id)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    # 3生成一天新闻数据

    news = News()
    news.title = title
    news.category_id = category_id
    news.digest = digest
    news.content = content

    # 读取二进制文件图片
    try:
        img_bytes = img_file.read()
        file_name = file_upload(img_bytes)      #新闻上传使用七牛封装函数
        news.index_image_url = QINIU_DOMIN_PREFIX + file_name
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])  # 与前段定义的规则包文档

    #设置其他数据
    news.source="个人发布"
    news.user_id=user.id    #作者表主键id
    news.status = 1   #发布状态内置属性

    #添加到数据库
    db.session.add(news)
    # try:  #可以不提交，内置提交数据库
    #     db.session.commit()
    # except BaseException as e:
    #     #包装进日记做记录
    #     current_app.logger.error(e)
    #     return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])  # 与前段定义的规则包文档

    # 4json返回数据传入模板渲染
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])  # 与前段定义的规则包文档


# 我的发布
@user_blu.route('/news_list')
@user_login_data
def news_list():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)

    # 1获取参数  #需要上传文件用form
    p = request.form.get("p",1)

    # 2校验参数
    try:
        p = int(p)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    #查询当前用户发布的新闻 分页查询  发布时间倒序
    try:
        pn = user.news_list.order_by(News.create_time.desc()).paginate(p,USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        #包装进日记做记录
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    #数据封装到字典中
    data={
        "news_list":[news.to_review_dict() for news in pn.items],
        "total_page":pn.pages,
        "cur_page":pn.page
    }

    # 4json返回数据传入模板渲染
    return render_template("news/user_news_list.html", data=data)



# 我的关注
@user_blu.route('/user_follow')
@user_login_data
def user_follow():
    # 用户登陆g函数
    user = g.user
    if not user:  # 用户未登陆
        return abort(403)

    # 1获取参数
    p = request.args.get("p",1)

    # 2校验参数
    try:
        p = int(p)
    except BaseException as e:
        # 包装进日记做记录
        current_app.logger.error(e)
        return abort(403)

    #查询当前用户发布的新闻 分页查询  发布时间倒序
    try:
        pn = user.followed.paginate(p,USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        #包装进日记做记录
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])  # 与前段定义的规则包文档

    #数据封装到字典中
    data={
        "author_list":[user.to_dict() for user in pn.items],
        "total_page":pn.pages,
        "cur_page":pn.page
    }

    # 4json返回数据传入模板渲染
    return render_template("news/user_follow.html", data=data)
















